package moa.learners.reservoir;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import moa.learners.reservoir.AbstractSlides;


/**
 * Saves the contents of the Reservoir into ARFF files
 * (for later processing by Weka + WekaSP)
 *
 * To the given path and file name is added a sequential number
 *
 * @param <E> type of itemsets stored in the Reservoir
 */
public class DiskWriter<E extends Collection<String>> implements AbstractWriter<E> {
	private String pathAndFile;
	private long countWrites = 0;

	/**
	 * @param pathAndFile base name of the saved files (with complete path if necessary)
	 */
	public DiskWriter( String pathAndFile) {
		this.pathAndFile = pathAndFile;
	}


	public void Write( AbstractSlides<E> tanker) throws Exception {
		// complete file name
		countWrites++;
		String completeFileName = pathAndFile;
		NumberFormat nf = NumberFormat.getInstance();
		nf.setMinimumIntegerDigits(9);
		nf.setGroupingUsed(false);
		completeFileName += nf.format(countWrites) + ".arff";

		BufferedWriter bw = new BufferedWriter( new FileWriter(completeFileName));

		// retrieve list of all possible values for items
		HashSet<String> itemValues = new HashSet<String>();
		Iterator<String> iteClient = tanker.clientIterator();
		while( iteClient.hasNext()) {
			Iterator<E> iteItemSet = tanker.itemIterator(iteClient.next());
			while( iteItemSet.hasNext())
				itemValues.addAll(iteItemSet.next());
		}

		// header
		bw.write("@relation " + completeFileName); bw.newLine();
		bw.write("@attribute customer real"); bw.newLine();
		bw.write("@attribute date real"); bw.newLine();
		for( String item : itemValues) {
			bw.write("@attribute " + item + " {0,1}");
			System.out.println("attribute " + item);
			bw.newLine();
		}
		bw.newLine(); bw.write("@data"); bw.newLine();

		// data
		iteClient = tanker.clientIterator();
		long clientNumber = 1;
		while( iteClient.hasNext()) {
			Iterator<E> iteItemSet = tanker.itemIterator(iteClient.next());
			long numSequence = 0;
			while( iteItemSet.hasNext()) {
				bw.write(clientNumber + "," + numSequence);
				System.out.print("cli" + clientNumber + " seq " + numSequence + " -->");
				Collection<?> itemSet = (Collection<?>) iteItemSet.next();
				for( String attr : itemValues) {
					bw.write(",");
					//System.out.print(",");
					bw.write( itemSet.contains(attr) ? "1" : "0");
					//System.out.print( itemSet.contains(attr) ? "1" : "0");
					if (itemSet.contains(attr))
							System.out.print(" " + attr + " ");
				}

				bw.newLine();
				System.out.println();
				numSequence++;
			}
			clientNumber++;
		}

		bw.close();
	}
	
	public void WriteSeq( AbstractSlides<E> tanker) throws Exception {
		// complete file name
		countWrites++;
		String completeFileName = pathAndFile;
		NumberFormat nf = NumberFormat.getInstance();
		nf.setMinimumIntegerDigits(9);
		nf.setGroupingUsed(false);
		completeFileName += nf.format(countWrites) + ".arff";

		BufferedWriter bw = new BufferedWriter( new FileWriter(completeFileName));

		// retrieve list of all possible values for items
		HashSet<String> itemValues = new HashSet<String>();
		Iterator<String> iteClient = tanker.clientIterator();
		while( iteClient.hasNext()) {
			Iterator<E> iteItemSet = tanker.itemIterator(iteClient.next());
			while( iteItemSet.hasNext())
				itemValues.addAll(iteItemSet.next());
		}

		// header
		bw.write("@relation " + completeFileName); bw.newLine();
		bw.write("@attribute sequence STRING"); bw.newLine();
		bw.newLine(); bw.write("@data"); bw.newLine();
		
		// data
		iteClient = tanker.clientIterator();
		long clientNumber = 1;
		while( iteClient.hasNext()) {
			System.out.print("'");
			Iterator<E> iteItemSet = tanker.itemIterator(iteClient.next());
			long numSequence = 0;
			while( iteItemSet.hasNext()) {
				Collection<?> itemSet = (Collection<?>) iteItemSet.next();
				System.out.print(itemSet.toString());
				numSequence++;
			}
			System.out.println("'");
			clientNumber++;
		}

		bw.close();
	}
}
